/*
 * Copyright (C) 2024 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the 'License');
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an 'AS IS' BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "animator_option_napi.h"

namespace ImageKnifeC {
AnimatorOptionNapi::AnimatorOptionNapi(napi_env env, napi_value jsObject)
{
    env_ = env;
    napi_create_reference(env, jsObject, 1, &jsThis_);

    napi_value value;
    if (napi_get_named_property(env, jsObject, "state", &value) == napi_ok) {
        int32_t st = 0;
        napi_get_value_int32(env, value, &st);
        state = (ArkUI_AnimationStatus)st;
    }

    if (napi_get_named_property(env, jsObject, "iterations", &value) == napi_ok) {
        napi_get_value_int32(env, value, &iterations);
    }

    if (napi_get_named_property(env, jsObject, "reverse", &value) == napi_ok) {
        napi_get_value_bool(env, value, &reverse);
    }

    napi_valuetype type;
    if (napi_get_named_property(env, jsObject, "onStart", &value) == napi_ok) {
        napi_typeof(env, value, &type);
        if (type != napi_undefined) {
            napi_create_reference(env, value, 1, &onStart_);
            onStart = [this]() {this->CallJsFunction(onStart_);};
        }
    }

    if (napi_get_named_property(env, jsObject, "onFinish", &value) == napi_ok) {
        napi_typeof(env, value, &type);
        if (type != napi_undefined) {
            napi_create_reference(env, value, 1, &onFinish_);
            onFinish = [this]() {this->CallJsFunction(onFinish_);};
        }
    }

    if (napi_get_named_property(env, jsObject, "onPause", &value) == napi_ok) {
        napi_typeof(env, value, &type);
        if (type != napi_undefined) {
            napi_create_reference(env, value, 1, &onPause_);
            onPause = [this]() {this->CallJsFunction(onPause_);};
        }
    }

    if (napi_get_named_property(env, jsObject, "onCancel", &value) == napi_ok) {
        napi_typeof(env, value, &type);
        if (type != napi_undefined) {
            napi_create_reference(env, value, 1, &onCancel_);
            onCancel = [this]() {this->CallJsFunction(onCancel_);};
        }
    }

    if (napi_get_named_property(env, jsObject, "onRepeat", &value) == napi_ok) {
        napi_typeof(env, value, &type);
        if (type != napi_undefined) {
            napi_create_reference(env, value, 1, &onRepeat_);
            onRepeat = [this]() {this->CallJsFunction(onRepeat_);};
        }
    }
}

void AnimatorOptionNapi::CallJsFunction(napi_ref ref)
{
    napi_value thisValue;
    napi_value jsFunc;
    napi_get_reference_value(env_, jsThis_, &thisValue);
    napi_get_reference_value(env_, ref, &jsFunc);
    napi_call_function(env_, thisValue, jsFunc, 0, nullptr, nullptr);
}

AnimatorOptionNapi::~AnimatorOptionNapi()
{
    if (onStart != nullptr) {
        napi_delete_reference(env_, onStart_);
    }

    if (onFinish != nullptr) {
        napi_delete_reference(env_, onFinish_);
    }

    if (onPause != nullptr) {
        napi_delete_reference(env_, onPause_);
    }

    if (onCancel != nullptr) {
        napi_delete_reference(env_, onCancel_);
    }

    if (onRepeat != nullptr) {
        napi_delete_reference(env_, onRepeat_);
    }

    napi_delete_reference(env_, jsThis_);
}

}
